package com.ruoyi.zhgd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.zhgd.domain.*;
import com.ruoyi.zhgd.domain.bo.ZjNWarningUserMessageBo;
import com.ruoyi.zhgd.domain.vo.*;
import com.ruoyi.zhgd.mapper.*;
import com.ruoyi.zhgd.service.IZjNWarningUsingService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.zhgd.domain.bo.ZjNLaboratoryGroutingRequiresBo;
import com.ruoyi.zhgd.service.IZjNLaboratoryGroutingRequiresService;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 压浆技术要求参数Service业务层处理
 *
 * @author tll
 * @date 2023-11-02
 */
@RequiredArgsConstructor
@Service
@DS("sjcj")
public class ZjNLaboratoryGroutingRequiresServiceImpl implements IZjNLaboratoryGroutingRequiresService {

    private final ZjNLaboratoryGroutingRequiresMapper baseMapper;

    private final GroutingRecordMapper groutingRecordMapper;

    private final IZjNWarningUsingService iZjNWarningUsingService;

    private final ZjNWarningUserMessageMapper zjNWarningUserMessageMapper;

    private final ZjNWarningZlyjMapper zjNWarningZlyjMapper;

    private final ZjNWarningUsingMapper zjNWarningUsingMapper;

    private final SysDeptMapper sysDeptMapper;

    /**
     * 查询压浆技术要求参数
     */
    @Override
    public ZjNLaboratoryGroutingRequiresVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询压浆技术要求参数列表
     */
    @Override
    public TableDataInfo<ZjNLaboratoryGroutingRequiresVo> queryPageList(ZjNLaboratoryGroutingRequiresBo bo, PageQuery pageQuery) {
        Long deptId = LoginHelper.getDeptId();
        List<SysDept> collect = iZjNWarningUsingService.getDeptTreeTop(deptId);
        List<Long> deptIds = collect.stream().map(SysDept::getDeptId).collect(Collectors.toList());
        bo.setDeptIds(deptIds);
        Page<ZjNLaboratoryGroutingRequiresVo> result = baseMapper.page(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询压浆技术要求参数列表
     */
    @Override
    public List<ZjNLaboratoryGroutingRequiresVo> queryList(ZjNLaboratoryGroutingRequiresBo bo) {
        LambdaQueryWrapper<ZjNLaboratoryGroutingRequires> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZjNLaboratoryGroutingRequires> buildQueryWrapper(ZjNLaboratoryGroutingRequiresBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZjNLaboratoryGroutingRequires> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getBaseCode()), ZjNLaboratoryGroutingRequires::getBaseCode, bo.getBaseCode());
        lqw.like(StringUtils.isNotBlank(bo.getName()), ZjNLaboratoryGroutingRequires::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getInsertBy()), ZjNLaboratoryGroutingRequires::getInsertBy, bo.getInsertBy());
        lqw.eq(bo.getInsertTime() != null, ZjNLaboratoryGroutingRequires::getInsertTime, bo.getInsertTime());
        lqw.eq(StringUtils.isNotBlank(bo.getDeptId()), ZjNLaboratoryGroutingRequires::getDeptId, bo.getDeptId());
        lqw.eq(StringUtils.isNotBlank(bo.getDeptPkid()), ZjNLaboratoryGroutingRequires::getDeptPkid, bo.getDeptPkid());
        lqw.eq(bo.getInflowPressureMaxVal() != null, ZjNLaboratoryGroutingRequires::getInflowPressureMaxVal, bo.getInflowPressureMaxVal());
        lqw.eq(bo.getInflowPressureMinVal() != null, ZjNLaboratoryGroutingRequires::getInflowPressureMinVal, bo.getInflowPressureMinVal());
        lqw.eq(bo.getHoldingTimeMaxVal() != null, ZjNLaboratoryGroutingRequires::getHoldingTimeMaxVal, bo.getHoldingTimeMaxVal());
        lqw.eq(bo.getHoldingTimeMinVal() != null, ZjNLaboratoryGroutingRequires::getHoldingTimeMinVal, bo.getHoldingTimeMinVal());
        lqw.eq(bo.getWaterCementRatioMaxVal() != null, ZjNLaboratoryGroutingRequires::getWaterCementRatioMaxVal, bo.getWaterCementRatioMaxVal());
        lqw.eq(bo.getWaterCementRatioMinVal() != null, ZjNLaboratoryGroutingRequires::getWaterCementRatioMinVal, bo.getWaterCementRatioMinVal());
        lqw.eq(bo.getInitialFlowVelocityMaxVal() != null, ZjNLaboratoryGroutingRequires::getInitialFlowVelocityMaxVal, bo.getInitialFlowVelocityMaxVal());
        lqw.eq(bo.getInitialFlowVelocityMinVal() != null, ZjNLaboratoryGroutingRequires::getInitialFlowVelocityMinVal, bo.getInitialFlowVelocityMinVal());
        return lqw;
    }

    /**
     * 新增压浆技术要求参数
     */
    @Override
    public Boolean insertByBo(ZjNLaboratoryGroutingRequiresBo bo) {
        ZjNLaboratoryGroutingRequires add = BeanUtil.toBean(bo, ZjNLaboratoryGroutingRequires.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改压浆技术要求参数
     */
    @Override
    public Boolean updateByBo(ZjNLaboratoryGroutingRequiresBo bo) {
        ZjNLaboratoryGroutingRequires update = BeanUtil.toBean(bo, ZjNLaboratoryGroutingRequires.class);
        validEntityBeforeSave(update);
        update.setUpdateBy(LoginHelper.getLoginUser().getUsername());
        update.setUpdateTime(new Date());
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ZjNLaboratoryGroutingRequires entity){
        //TODO 做一些数据校验,如唯一约束
        if (ObjectUtils.isEmpty(entity.getDelFlag())) {
            entity.setDelFlag("0");
        }
        if (ObjectUtils.isEmpty(entity.getInsertBy()) && ObjectUtils.isEmpty(entity.getUpdateBy())) {
            entity.setInsertBy(LoginHelper.getLoginUser().getUsername());
            entity.setUpdateBy(LoginHelper.getLoginUser().getUsername());
        }
        if (ObjectUtils.isEmpty(entity.getInsertTime()) && ObjectUtils.isEmpty(entity.getUpdateTime())) {
            entity.setInsertTime(new Date());
            entity.setUpdateTime(new Date());
        }
    }

    /**
     * 批量删除压浆技术要求参数
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    private String status = null;

    // 进浆压力上下限
    private BigDecimal inflowPressureMinVal = BigDecimal.valueOf(0);
    private BigDecimal inflowPressureMaxVal = BigDecimal.valueOf(0);
    // 保压时间上下限
    private BigDecimal holdingTimeMinVal = BigDecimal.valueOf(0);
    private BigDecimal holdingTimeMaxVal = BigDecimal.valueOf(0);
    // 水胶比上下限
    private BigDecimal waterCementRatioMinVal = BigDecimal.valueOf(0);
    private BigDecimal waterCementRatioMaxVal = BigDecimal.valueOf(0);
    // 初始流动速度上下限
    private BigDecimal initialFlowVelocityMinVal = BigDecimal.valueOf(0);
    private BigDecimal initialFlowVelocityMaxVal = BigDecimal.valueOf(0);

    private List<Object> unqualifiedParams = new ArrayList<>(); // 不合格参数
    private final String TEXT1 = " ";
    private final String TEXT2 = ",";
    private final String TEXT3 = "~";

    @Override
    @Transactional
    public void isQualified(String linkCode) {
        if (ObjectUtils.isEmpty(linkCode)) {
            throw new ServiceException("linkCode不能为空");
        }
        // 根据linkCode获取要判定的业务数据
        List<GroutingRecordResVo> vos = groutingRecordMapper.selectByLinkCode(linkCode);
        if (CollectionUtils.isNotEmpty(vos)) {
            String deptId = ObjectUtils.isNotEmpty(vos.get(0).getDeptId()) ? vos.get(0).getDeptId() : null;
            if (ObjectUtils.isEmpty(deptId)) {
                throw new ServiceException("没有部门信息，无法校验！");
            }
            GroutingRecordResVo recordResVo = vos.get(0);
            // 根据deptId获取祖级列表
            SysDept dept = sysDeptMapper.getById(Long.valueOf(deptId));
            String ancestors = ObjectUtils.isNotEmpty(dept) ? dept.getAncestors() : null;
            String[] ids = ObjectUtils.isNotEmpty(ancestors) ? ancestors.split(",") : new String[]{} ;
            // 获取最新技术要求
            ZjNLaboratoryGroutingRequires requirement = baseMapper.getByDeptId(deptId, ids);
            if (ObjectUtils.isNotEmpty(requirement)) {
                List<GroutingRecord> recUpdateList = new ArrayList<>();
                setRequirementData(requirement);
                recUpdateList = estimateData(vos, recUpdateList);
                // 更新record表
                if (CollectionUtils.isNotEmpty(recUpdateList) && recUpdateList.size() > 0) {
                    groutingRecordMapper.updateBatchById(recUpdateList);
                }
                // 推送消息并保存
                if (CollectionUtils.isNotEmpty(recUpdateList) && recUpdateList.size() > 0 && ObjectUtils.isNotEmpty(recordResVo)) {
                    sendMsg(deptId, recordResVo, 1);
                }
            }
        }

    }

    /**
     * 压浆手动校验是否合格并更新数据
     */
    @Override
    @Transactional
    public void isQualifiedList(GroutingRecordVo params) {
        if (ObjectUtils.isEmpty(params.getDeptIdList())) {
            throw new ServiceException("部门id不能为空");
        }
        List<GroutingRecord> recUpdateList = new ArrayList<>();

        for (String deptId : params.getDeptIdList()) {
            // 根据deptId获取祖级列表
            SysDept dept = sysDeptMapper.getById(Long.valueOf(deptId));
            String ancestors = ObjectUtils.isNotEmpty(dept) ? dept.getAncestors() : null;
            String[] ids = ObjectUtils.isNotEmpty(ancestors) ? ancestors.split(",") : new String[]{} ;
            // 获取最新技术要求
            ZjNLaboratoryGroutingRequires requirement = baseMapper.getByDeptId(deptId, ids);
            if (ObjectUtils.isEmpty(requirement)) {
                continue;
            }
            // 获取要判定的压浆数据
            List<GroutingRecordResVo> vos = groutingRecordMapper.check(deptId);
            GroutingRecordResVo recordResVo = ObjectUtils.isNotEmpty(vos.get(0)) ? vos.get(0) : new GroutingRecordResVo();
            setRequirementData(requirement);
            recUpdateList = estimateData(vos, recUpdateList);
            // 推送消息并保存
            if (CollectionUtils.isNotEmpty(recUpdateList) && recUpdateList.size() > 0 && ObjectUtils.isNotEmpty(recordResVo)) {
                sendMsg(deptId, recordResVo, 0);
            }
            // 更新record表
            if (CollectionUtils.isNotEmpty(recUpdateList) && recUpdateList.size() > 0) {
                recUpdateList.forEach(item -> {
                    if (ObjectUtils.isNotEmpty(item)) {
                        groutingRecordMapper.statusUpdate(item);
                    }
                });
            }
        }

    }

    /**
     * 手动校验(多选)
     *
     * @param bo
     */
    @Override
    @Transactional
    public void handCheck(ZjNLaboratoryGroutingRequiresBo bo) {
        if (ObjectUtils.isEmpty(bo.getIds())) {
            throw new ServiceException("ID列表不能为空");
        }
        // 根据id查询linkCode
        List<String> ids = bo.getIds();
        List<GroutingRecordResVo> vos = groutingRecordMapper.getListByIds(ids);
        // 获取linkCode
        List<String> linkCodes = vos.stream().map(GroutingRecordResVo::getLinkCode).collect(Collectors.toList());
        for (String linkCode : linkCodes) {
            // 调用判断方法
            isQualified(linkCode);
        }
    }

    public void setRequirementData(ZjNLaboratoryGroutingRequires requirement){
        // 技术要求格式转换
        // 进浆压力上下限
        inflowPressureMinVal = requirement.getInflowPressureMinVal();
        inflowPressureMaxVal = requirement.getInflowPressureMaxVal();
        // 保压时间上下限
        holdingTimeMinVal = requirement.getHoldingTimeMinVal();
        holdingTimeMaxVal = requirement.getHoldingTimeMaxVal();
        // 水胶比上下限
        waterCementRatioMinVal = requirement.getWaterCementRatioMinVal();
        waterCementRatioMaxVal = requirement.getWaterCementRatioMaxVal();
        // 初始流动速度上下限
        initialFlowVelocityMinVal = requirement.getInitialFlowVelocityMinVal();
        initialFlowVelocityMaxVal = requirement.getInitialFlowVelocityMaxVal();
    }

    public List<GroutingRecord> estimateData(List<GroutingRecordResVo> vos, List<GroutingRecord> recUpdateList) {
        unqualifiedParams = new ArrayList<>();
        // 判定是否合格
        for (GroutingRecordResVo vo : vos) {
            status = null;
            BigDecimal inflowPressure = vo.getInflowPressure();
            Integer holdingTime = vo.getHoldingTime();
            Double waterCementRatio = ObjectUtils.isNotEmpty(vo.getWaterCementRatio()) ? Double.parseDouble(vo.getWaterCementRatio()) : null;
            BigDecimal initialFlowVelocity = vo.getInitialFlowVelocity();
            // 进浆压力
            if (ObjectUtils.isNotEmpty(inflowPressure) && ObjectUtils.isNotEmpty(inflowPressureMinVal) && ObjectUtils.isNotEmpty(inflowPressureMaxVal)) {
                if (inflowPressure.compareTo(inflowPressureMinVal) != -1 && inflowPressure.compareTo(inflowPressureMaxVal) != 1) {
                    // 保压时间
                    if (ObjectUtils.isNotEmpty(holdingTime) && ObjectUtils.isNotEmpty(holdingTimeMinVal) && ObjectUtils.isNotEmpty(holdingTimeMaxVal)) {
                        if (holdingTime.compareTo(holdingTimeMinVal.intValue()) != -1 && holdingTime.compareTo(holdingTimeMaxVal.intValue()) != 1) {
                            // 水胶比
                            if (ObjectUtils.isNotEmpty(waterCementRatio) && ObjectUtils.isNotEmpty(waterCementRatioMinVal) && ObjectUtils.isNotEmpty(waterCementRatioMaxVal)) {
                                if (waterCementRatio.compareTo(waterCementRatioMinVal.doubleValue()) != -1 && waterCementRatio.compareTo(waterCementRatioMaxVal.doubleValue()) != 1) {
                                    // 初始流动速度
                                    if (ObjectUtils.isNotEmpty(initialFlowVelocity) && ObjectUtils.isNotEmpty(initialFlowVelocityMinVal) && ObjectUtils.isNotEmpty(initialFlowVelocityMaxVal)) {
                                        if (initialFlowVelocity.compareTo(initialFlowVelocityMinVal) != -1 && initialFlowVelocity.compareTo(initialFlowVelocityMaxVal) != 1) {
                                            vo.setStatus("1");
                                            status = "1";
                                        } else {
                                            vo.setStatus("0");
                                            status = "0";
                                            // 保存不合格参数
                                            unqualifiedParams.add("孔号:" + vo.getHoleNumber() + TEXT2 + "初始流动速度:" + vo.getInitialFlowVelocity()
                                                + "超出上下限范围(" + initialFlowVelocityMinVal + TEXT3 + initialFlowVelocityMaxVal + ")" + TEXT2);
                                        }
                                    } else {
                                        vo.setStatus("0");
                                        status = "0";
                                        // 保存不合格参数
                                        unqualifiedParams.add("孔号:" + vo.getHoleNumber() + TEXT2 + "初始流动速度:" + vo.getInitialFlowVelocity()
                                            + "超出上下限范围(" + initialFlowVelocityMinVal + TEXT3 + initialFlowVelocityMaxVal + ")" + TEXT2);
                                    }
                                } else {
                                    vo.setStatus("0");
                                    status = "0";
                                    // 保存不合格参数
                                    unqualifiedParams.add("孔号:" + vo.getHoleNumber() + TEXT2 + "水胶比:" + vo.getWaterCementRatio()
                                        + "超出上下限范围(" + waterCementRatioMinVal + TEXT3 + waterCementRatioMaxVal + ")" + TEXT2);
                                }
                            } else {
                                vo.setStatus("0");
                                status = "0";
                                // 保存不合格参数
                                unqualifiedParams.add("孔号:" + vo.getHoleNumber() + TEXT2 + "水胶比:" + vo.getWaterCementRatio()
                                    + "超出上下限范围(" + waterCementRatioMinVal + TEXT3 + waterCementRatioMaxVal + ")" + TEXT2);
                            }
                        } else {
                            vo.setStatus("0");
                            status = "0";
                            // 保存不合格参数
                            unqualifiedParams.add("孔号:" + vo.getHoleNumber() + TEXT2 + "保压时间:" + vo.getHoldingTime()
                                + "超出上下限范围(" + holdingTimeMinVal + TEXT3 + holdingTimeMaxVal + ")" + TEXT2);
                        }
                    } else {
                        vo.setStatus("0");
                        status = "0";
                        // 保存不合格参数
                        unqualifiedParams.add("孔号:" + vo.getHoleNumber() + TEXT2 + "保压时间:" + vo.getHoldingTime()
                            + "超出上下限范围(" + holdingTimeMinVal + TEXT3 + holdingTimeMaxVal + ")" + TEXT2);
                    }
                } else {
                    vo.setStatus("0");
                    status = "0";
                    // 保存不合格参数
                    unqualifiedParams.add("孔号:" + vo.getHoleNumber() + TEXT2 + "进浆压力:" + vo.getInflowPressure()
                        + "超出上下限范围(" + inflowPressureMinVal + TEXT3 + inflowPressureMaxVal + ")" + TEXT2);
                }
            } else {
                vo.setStatus("0");
                status = "0";
                // 保存不合格参数
                unqualifiedParams.add("孔号:" + vo.getHoleNumber() + TEXT2 + "进浆压力:" + vo.getInflowPressure()
                    + "超出上下限范围(" + inflowPressureMinVal + TEXT3 + inflowPressureMaxVal + ")" + TEXT2);
            }
            if (ObjectUtils.isNotEmpty(vo.getId()) && ObjectUtils.isNotEmpty(status)) {
                GroutingRecord record = new GroutingRecord();
                record.setId(vo.getId());
                record.setStatus(status);
                recUpdateList.add(record);
            }
        }
        return recUpdateList;
    }

    /**
     * 短信推送及预警信息保存
     * @param deptId
     * @param recordVo
     */
    private void sendMsg(String deptId, GroutingRecordResVo recordVo, int isSend) {
        String message = null;
        int send = 1;
        // 是否发送消息 1发送 0不发
        if (isSend == 1) {
            if (!"1".equals(status)) {
                // 发送内容
                // 短信推送样例：【山东高速】xx标段，xx拌合站的xx施工部位采用的xx配方的外加剂1产生了初级预警,超出标准值或低于标准值xx%。
                String deptName = ObjectUtils.isNotEmpty(recordVo.getDeptName()) ? "【" + recordVo.getDeptName() : "【";
                String instrumentManufacturer = ObjectUtils.isNotEmpty(recordVo.getInstrumentManufacturer()) ? recordVo.getInstrumentManufacturer() : "";
                String deviceName = ObjectUtils.isNotEmpty(recordVo.getDeviceName()) ? recordVo.getDeviceName() : "";
                String pileNumber = "桩号:" + (ObjectUtils.isNotEmpty(recordVo.getPileNumber()) ? recordVo.getPileNumber() : "");
                String beamNumber = "梁号:" + (ObjectUtils.isNotEmpty(recordVo.getBeamNumber()) ? recordVo.getBeamNumber() : "");
                String tensioningBeamType = "梁型:" + (ObjectUtils.isNotEmpty(recordVo.getTensioningBeamType()) ? recordVo.getTensioningBeamType() : "");
//                String start = "【山东高速】";
                String start = "";
                String separator = " ";
                String common = "】的压浆数据产生了预警信息: ";
                // 不合格参数
                String params = "";
                for (Object str : unqualifiedParams) {
                    params += str;
                }
                params += "不合格;";
                message =  start + deptName + separator + deviceName + separator + instrumentManufacturer + separator + pileNumber + separator + beamNumber + separator + tensioningBeamType + common + params;
            }
            // 根据deptId获取祖级列表
            SysDept dept = sysDeptMapper.getById(Long.valueOf(deptId));
            String ancestors = ObjectUtils.isNotEmpty(dept) ? dept.getAncestors() : null;
            String[] ids = ObjectUtils.isNotEmpty(ancestors) ? ancestors.split(",") : new String[]{} ;
            // 根据部门id获取预警标识
            ZjNWarningUsing entity = zjNWarningUsingMapper.getByDeptId(deptId, ids);
            Long msgZlyj = ObjectUtils.isNotEmpty(entity) ? entity.getUsingMsgZlyj() : 0;
            if (msgZlyj == 1 && !"1".equals(status)) {
                // 发送人获取:
                ZjNWarningUserMessageBo bo = new ZjNWarningUserMessageBo();
                bo.setId(deptId);
                QueryWrapper<ZjNWarningUserMessage> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("a.del_flag", "0");
                wrapper1.eq("u.del_flag", "0");
                wrapper1.like("a.warn_val_zlyj", "%2%");
                List<ZjNWarningUserMessageVo> list = zjNWarningUserMessageMapper.getZlyjList(wrapper1, bo);
                List<String> phonenumber = list.stream().map(ZjNWarningUserMessageVo::getPhonenumber).collect(Collectors.toList());
                // 预警发送及保存
                try {
                    send = iZjNWarningUsingService.send(phonenumber, message);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("短信发送失败");
                }
            }
        }
        // 不合格则产生预警信息
        if (!"1".equals(status)) {
            // 推送失败 返1 成功 返0
            ZjNWarningZlyj zjNWarningZlyj = new ZjNWarningZlyj();
            zjNWarningZlyj.setType("2");
            zjNWarningZlyj.setInsterTime(new Date());
            zjNWarningZlyj.setRemark(message);
            zjNWarningZlyj.setBusinessId(recordVo.getId());
            zjNWarningZlyj.setStatus(String.valueOf(send));
            zjNWarningZlyj.setDisposalStatus(1); // 未处置
            zjNWarningZlyjMapper.insert(zjNWarningZlyj);
        }
    }

}
